package com.evolved.automata.experimental;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;

public class StaticTools {

	/*****************************
	 * BEGIN of Static Enumerations
	 ***************************** 
	 */
	public static enum AgentType
	{
		SIMPLE_AUTONOMOUS_ROVER,
		AUTONOMOUS_ROVER_TRAINER,
		DYNAMICAL_AUTONOMOUS_ROVER
	}
	
	public static enum SensoryMototProviderType
	{
		SRV1
	}
	
	public static enum GenomeType
	{
		SIMPLE_PROBABILITSTIC
	}
	

	
	public static final int INF_IF_MISSING_DATA_THEN_NO_MATCH=1;
	public static final int INF_IF_MISSING_DATA_THEN_USE_BAYESIAN=2;
	public static final int INF_IF_NO_MATCH_THEN_USE_PRIOR=4;
	public static final int INF_IF_NO_MATCH_THEN_USE_UNIVERSAL=8;
	public static final int INF_IF_NO_MATCH_THEN_USE_10_NEIBORHO0D=16;
	public static final int INF_IF_NO_MATCH_THEN_USE_25_NEIBORHO0D=32;
	public static final int INF_IF_NO_MATCH_THEN_USE_33_NEIBORHO0D=64;
	public static final int INF_IF_NO_MATCH_THEN_USE_50_NEIBORHO0D=128;
	public static final int INF_IF_NO_MATCH_THEN_USE_100_NEIBORHO0D=256;
	public static final int INF_USING_UNIVERSAL=512;
	public static final int INF_USING_STANDARD=1024;
	public static final int INF_USING_PRIOR=2048;
	public static final int INF_USING_NEIGHBORHOOD=4096;
	public static final int INF_IF_MATCH_FAVOR_PREVIOUS=8192;
	public static final int INF_IF_NO_MATCH_THEN_CLUSTER_10=8192*2;
	

	
	/*****************************
	 * END of Static Enumerations
	 ***************************** 
	 */
	
	
	/*****************************
	 * BEGIN of Special Inner Classes
	 ***************************** 
	 */
	
	public static interface SimpleDataParser
	{
		public void AddBoolean(boolean data, int index);
		public void AddInteger(int data, int index);
	}
	
	/*****************************
	 * END of Special Inner Classes
	 ***************************** 
	 */
	
	/*****************************
	 * BEGIN of Special Factory Methods
	 ***************************** 
	 */
	
	public static SRV1SensoryMotorProvider GetTypeFromName(String name)
	{
		if (name.equals("SRV1"))
			return new SRV1SensoryMotorProvider();
		return null;
	}
	
	
	
	
	
	public static Serializer GetSerializer(String typeId)
	{
		if (typeId==null)
			return null;
		
		if (typeId.equalsIgnoreCase("BehaviorDistribution"))
		{
			return new BehaviorDistribution();
		}
		else if (typeId.equalsIgnoreCase("ProbabilisticGenome"))
		{
			return new ProbabilisticGenome();
		}
		else if (typeId.equalsIgnoreCase("ProbabilisticLearningAgent"))
		{
			return new ProbabilisticLearningAgent();
		}
		else if (typeId.equalsIgnoreCase("AgentInfo"))
			return new AgentInfo();
		else if (typeId.equalsIgnoreCase("GeneManager"))
			return new GeneManager();
		else if (typeId.equalsIgnoreCase("AgentManager"))
			return new AgentManager();
		else if (typeId.equalsIgnoreCase("SRV1SensoryMotorProvider")) // Not implemented yet
			return null;
		else if (typeId.equalsIgnoreCase("ProbabilisticTrainingAgent"))
			return new ProbabilisticTrainingAgent();
		else if (typeId.equalsIgnoreCase(""))
			return null;
		
		return null;
	}
	
	public static  UtilityAndPerferenceModule UtilityTypeNameToObject(int typeId)
	{
		switch (typeId)
		{
			case UtilityAndPerferenceModule.KEEP_DISTANCE_GREATER_THAN_MINIMUM:
				return new SimpleRobotUtilityInterpreter();
			case UtilityAndPerferenceModule.ACCEPT_ANY:
				return new MimicPreferenceModule();
			case UtilityAndPerferenceModule.SIMPLE_AVOIDANCE_ONLY:
				return new SimpleAvoidancePreference();
				
		}
		return null;
	}
	
	/*****************************
	 * END of Special Factory Methods
	 ***************************** 
	 */
	
	
	/*****************************
	 * BEGIN of Simple File Access Methods
	 ***************************** 
	 */
	
	public static void ParseBooleanStringValues(String booleanStringList, StaticTools.SimpleDataParser parser)
	{
		boolean[] bInput = ReadStringIntToBooleanArray(booleanStringList,",");
		if (bInput==null)
			return;
		for (int i=0;i<bInput.length;i++)
			parser.AddBoolean(bInput[i], i);
	}
	
	public static void ParseIntStringValues(String intStringList, StaticTools.SimpleDataParser parser)
	{
		int[] input = ReadStringIntArray(intStringList,",");
		if (input==null)
			return;
		for (int i=0;i<input.length;i++)
			parser.AddInteger(input[i], i);
	}
	
	
	public static void WriteRawData(BufferedWriter writer, String data)
	{
		try
		{
			writer.write(":"+data);
			writer.newLine();
		}
		catch (Exception e)
		{
			java.io.StringWriter traceText = new java.io.StringWriter();
			java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
			e.printStackTrace(pWriter);
			pWriter.close();
			throw new RuntimeException(traceText.toString());
		}
	}
	
	public static void WriteRawData(BufferedWriter writer, int data)
	{
		try
		{
			writer.write(":"+data);
			writer.newLine();
		}
		catch (Exception e)
		{
			java.io.StringWriter traceText = new java.io.StringWriter();
			java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
			e.printStackTrace(pWriter);
			pWriter.close();
			throw new RuntimeException(traceText.toString());
		}
	}
	
	public static void WriteRawData(BufferedWriter writer, double data)
	{
		try
		{
			writer.write(":"+data);
			writer.newLine();
		}
		catch (Exception e)
		{
			java.io.StringWriter traceText = new java.io.StringWriter();
			java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
			e.printStackTrace(pWriter);
			pWriter.close();
			throw new RuntimeException(traceText.toString());
		}
	}
	
	
	public static void WriteArray(BufferedWriter writer, boolean[] data)
	{
		WriteArray(writer,data,",");
	}
	
	public static void WriteArray(BufferedWriter writer, boolean[] data,String delimiter)
	{
		try
		{
			String Data;
		
			Data=WriteArrayString(data,delimiter);
			writer.write(Data);
			writer.newLine();
		}
		catch (Exception e)
		{
			java.io.StringWriter traceText = new java.io.StringWriter();
			java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
			e.printStackTrace(pWriter);
			pWriter.close();
			throw new RuntimeException(traceText.toString());
		}
	}
	
		
	
	public static void WriteArray(BufferedWriter writer, int[] data)
	{
		WriteArray(writer,data,",");
	}
	

	public static void WriteArray(BufferedWriter writer, int[] data,String delimiter)
	{
		try
		{
		String Data;
		
			Data=WriteArrayString(data,delimiter);
			writer.write(Data);
			writer.newLine();
		}
		catch (Exception e)
		{
			java.io.StringWriter traceText = new java.io.StringWriter();
			java.io.PrintWriter pWriter = new java.io.PrintWriter(traceText,true);
			e.printStackTrace(pWriter);
			pWriter.close();
			throw new RuntimeException(traceText.toString());
		}
	}
	
	/*****************************
	 * END of Simple File Access Methods
	 ***************************** 
	 */
	
	/*****************************
	 * BEGIN of Miscellaneous Helper Methods
	 ***************************** 
	 */
	
	public static String WriteArrayString(int[] data)
	{
		return WriteArrayString(data,",");
	}
	
	
	public static String WriteArrayString(boolean[] data)
	{
		return WriteArrayString(data,",");
	}
	
	
	
	public static String WriteArrayString(int[] data, String delimiter)
	{
		if (data==null)
			return null;
		StringBuffer Data = new StringBuffer();
	
		Data.append(String.format(":%1$s", data[0]));
			
			
		for (int i=1;i<data.length;i++)
		{
			Data.append(String.format("%1$s%2$s",delimiter, data[i]));
			
		}
			
		return Data.toString();
	}
	
	// TODO: Make useful overloads of these for different combinations of common delimiters and separtors
	public static String WriteArrayAsStringList(int[][] data)
	{
		if (data==null)
			return "";
		StringBuffer Data = new StringBuffer();
		String separator = " ";
		String startDelimiter = "(";
		String endDelimiter=")";
		Data.append(String.format("%2$s%1$s", WriteArrayAsStringList(data[0]," "),startDelimiter));
			
			
		for (int i=1;i<data.length;i++)
		{
			Data.append(String.format("%1$s%2$s",separator, WriteArrayAsStringList(data[i]," ")));
			
		}
		Data.append(endDelimiter);
		return Data.toString();
	}
	
	public static String WriteArrayAsStringList(int[] data, String separator)
	{
		if (data==null)
			return "";
		StringBuffer Data = new StringBuffer();
		String startDelimiter = "(";
		String endDelimiter=")";
		Data.append(String.format("%2$s%1$s", data[0],startDelimiter));
			
			
		for (int i=1;i<data.length;i++)
		{
			Data.append(String.format("%2$s%1$s",data[i],separator));
			
		}
		Data.append(endDelimiter);
		return Data.toString();
	}
	
	
	public static String WriteArrayString(boolean[] data, String delimiter)
	{
		if (data==null)
			return null;
		StringBuffer Data = new StringBuffer();
	
		Data.append(String.format(":%1$s", (data[0])?1:0));
			
			
		for (int i=1;i<data.length;i++)
		{
			Data.append(String.format("%1$s%2$s",delimiter, (data[i])?1:0));
			
		}
			
		return Data.toString();
	}
	
	
	
	public static int[] ReadStringIntArray(String dataString, String delimiter)
	{
		int[] out=null;
		if ((dataString==null)||(dataString.length()==0))
			return null;
		String[] split=SplitData(dataString,delimiter);
		out = new int[split.length];
		for (int i=0;i<split.length;i++)
		{
			out[i]=Integer.parseInt(split[i]);
		}
		return out;
	}
	
	
	public static boolean[] ReadStringIntToBooleanArray(String dataString, String delimiter)
	{
		boolean[] out=null;
		if ((dataString==null)||(dataString.length()==0))
			return null;
		String[] split=SplitData(dataString,delimiter);
		out = new boolean[split.length];
		int iValue;
		for (int i=0;i<split.length;i++)
		{
			iValue=Integer.parseInt(split[i]);
			out[i]=(iValue==0)?false:true;
		}
		return out;
	}
	
	
	
	
	public static String[] SplitData(String lineInput)
	{
		return SplitData(lineInput,":");
	}
	
	
	public static String[] SplitData(String lineInput, String delimiter)
	{
		return lineInput.split("\\"+delimiter);
	}
	
	/*****************************
	 * END of Miscellaneous Helper Methods
	 ***************************** 
	 */
	
	public static long j_CurrentTimeMilli=System.currentTimeMillis();
	public static String j_TraceFileFullName = "C:\\tracelog.log";
	
	static 
	{
		java.io.File f = new java.io.File(j_TraceFileFullName);
		if (f.exists())
		{
			f.delete();
		}
		
	}
	
	public static void TraceLog(String log)
	{
		long now = System.currentTimeMillis();
		long offset = now-j_CurrentTimeMilli;
		String message = "%1$s: %2$s";
		BufferedWriter writer=null;
		try
		{
			writer = new BufferedWriter(new FileWriter(j_TraceFileFullName,true));
			WriteRawData(writer, String.format(message, offset,log));
			j_CurrentTimeMilli=now;
		}
		catch (Exception e)
		{
			
		}
		finally
		{
			try
			{
				writer.close();
			}
			catch (Exception e2)
			{
				
			}
		}
		
	}
	
}
